﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Http;
using System.Data.Entity;
using System.Web.Routing;
using System.Web.Mvc;

using Microsoft.Practices.Unity;

using ERPStore.Extensions;
using ERPStore.Web.Routing;

using EventBrokR;

namespace ERPStore.Coupons
{
	public class PluginInit : ERPStore.Extensibility.PluginInit
	{
		public PluginInit()
		{
			Container = GlobalConfiguration.Configuration.DependencyResolver.GetContainer();
		}

		Microsoft.Practices.Unity.IUnityContainer Container { get; set; }

		public override void AddServices()
		{
			var settings = new Models.Settings();
			settings.BindFromConfiguration(Configuration.ConfigurationSettings.AppSettings);
			Container.RegisterInstance(settings);

			if (settings.RepositoryName == "mock")
			{
				Container.RegisterType<CloudSoft.Repositories.IRepository<Repositories.CouponDbContext>, CloudSoft.Repositories.MemoryRepository<ERPStore.Coupons.Repositories.CouponDbContext>>(new ContainerControlledLifetimeManager());
			}
			else
			{
				Container.RegisterType<CloudSoft.Repositories.IRepository<Repositories.CouponDbContext>, CloudSoft.Repositories.SqlRepository<Repositories.CouponDbContext>>();
				Container.RegisterType<CloudSoft.Repositories.IRepositoryInitializer, CloudSoft.Repositories.Initializers.SqlSchemaInitializer<Repositories.CouponDbContext>>("sqlcouponschemainitializer");
				Container.RegisterType<CloudSoft.Repositories.IDbContextFactory<Repositories.CouponDbContext>, Repositories.DbContextFactory>(new PerThreadLifetimeManager());
			}

			Container.RegisterType<ERPStore.Services.IIncentiveService, Services.IncentiveService>(new ContainerControlledLifetimeManager());
			Container.RegisterType<Services.AdminIncentiveService>(new ContainerControlledLifetimeManager());

			// Validator
			Container.RegisterType<global::FluentValidation.IValidator<Models.Coupon>, ModelValidators.CouponValidator>("Validator:" + typeof(Models.Coupon).FullName, new ContainerControlledLifetimeManager());

			var eb = Container.Resolve<EventBrokR.IPublisher>();
			// EventConsumers
			eb.Container.Register<EventConsumers.AddCouponToCartEventConsumer>();
			eb.Container.Register<EventConsumers.RemoveCouponFromCartEventConsumer>();

			// Auto Mapping
			AutoMapper.Mapper.CreateMap<Repositories.Datas.CouponData, Models.Coupon>()
				.ForMember(dest => dest.CreditAmount, opt => opt.MapFrom(origin => origin.CreditAmount.HasValue ? origin.CreditAmount.Value / 1000000.0m : new Nullable<decimal>()))
				.ForMember(dest => dest.DiscountPercent, opt => opt.MapFrom(origin => origin.DiscountPercent.HasValue ? origin.DiscountPercent.Value / 10000d : new Nullable<double>()))
				.ForMember(dest => dest.MinimumPurchase, opt => opt.MapFrom(origin => origin.MinimumPurchase.HasValue ? origin.MinimumPurchase.Value / 1000000m : new Nullable<decimal>()));

			AutoMapper.Mapper.CreateMap<Models.Coupon, Repositories.Datas.CouponData>()
				.ForMember(dest => dest.CreditAmount, opt => opt.MapFrom(origin => origin.CreditAmount.HasValue ? Convert.ToInt64(origin.CreditAmount.Value * 1000000) : new Nullable<long>()))
				.ForMember(dest => dest.DiscountPercent, opt => opt.MapFrom(origin => origin.DiscountPercent.HasValue ? Convert.ToInt32(origin.DiscountPercent.Value * 10000) : new Nullable<int>()))
				.ForMember(dest => dest.MinimumPurchase, opt => opt.MapFrom(origin => origin.MinimumPurchase.HasValue ? Convert.ToInt64(origin.MinimumPurchase.Value * 1000000) : new Nullable<long>()));

			AutoMapper.Mapper.CreateMap<Repositories.Datas.DiscountData, Models.CartDiscount>()
				.ForMember(dest => dest.Discount, opt => opt.MapFrom(origin => origin.Discount / 1000000m))
				.ForMember(dest => dest.DiscountWithTax, opt => opt.MapFrom(origin => origin.DiscountWithTax / 1000000m))
				.ForMember(dest => dest.Code, opt => opt.MapFrom(origin => origin.CouponCode));

			AutoMapper.Mapper.CreateMap<Models.CartDiscount, Repositories.Datas.DiscountData>()
				.ForMember(dest => dest.Discount, opt => opt.MapFrom(origin => Convert.ToInt64(origin.Discount * 1000000)))
				.ForMember(dest => dest.DiscountWithTax, opt => opt.MapFrom(origin => Convert.ToInt64(origin.DiscountWithTax * 1000000)))
				.ForMember(dest => dest.CouponCode, opt => opt.MapFrom(origin => origin.Code))
				.ForMember(dest => dest.MetaEntityId, opt => opt.UseValue(-53));

		}

		public override void Load()
		{
			var settings = Container.Resolve<Models.Settings>();

			if (settings.RepositoryName != "mock")
			{
				var initializer = Container.Resolve<CloudSoft.Repositories.IRepositoryInitializer>("sqlcouponschemainitializer");
				if (initializer != null)
				{
					initializer.Initialize("_erpstore_schema_coupons");
				}
			}

			var incentiveService = Container.Resolve<Services.AdminIncentiveService>();
			incentiveService.RegisterCouponProvider("shippingfree", typeof(Services.Providers.TransportCouponProvider));
			incentiveService.RegisterCouponProvider("globaldiscount", typeof(Services.Providers.GlobalDiscountProvider));
			incentiveService.RegisterCouponProvider("creditdiscount", typeof(Services.Providers.CreditDiscountProvider));
			incentiveService.RegisterCouponProvider("sandboxCoupon", typeof(Services.Providers.SandboxCouponProvider));
		}

		public override void RegisterRoutes()
		{
			RouteTable.Routes.MapERPStoreRoute(
				"Coupons"
				, "coupons/{action}/{id}"
				, new { controller = "Incentive", action = "Index", id = UrlParameter.Optional }
			);

			RouteTable.Routes.MapHttpRoute(
				"CouponsApi"
				, "api/coupons/{action}/{id}"
				, new { controller = "IncentiveApi", action = "Ping", id = UrlParameter.Optional }
			);

		}

	}
}
